package com.example.wechat;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.Base64;

import androidx.lifecycle.LiveData;

import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import retrofit2.Call;
import retrofit2.Callback;

public class ContactRepository {
    private final RetrofitClient AppDatabase;
    private ContactDao contactDao;
    private ContactApi contactApi;
    private ExecutorService executorService;

    public ContactRepository(RetrofitClient appDatabase, Context context) {
        AppDatabase = appDatabase;
        contactDao = AppDatabase.getInstance(context).contactDao();
        contactApi = RetrofitClient.getInstance(context).create(ContactApi.class);
        executorService = Executors.newSingleThreadExecutor();
    }

    public LiveData<List<Contact>> getAllContacts() {
        refreshContacts();
        return contactDao.getAllContacts();
    }

    public LiveData<List<Contact>> getContactsByGroup(String groupName) {
        return contactDao.getContactsByGroup(groupName);
    }

    public LiveData<List<String>> getAllGroups() {
        return contactDao.getAllGroups();
    }

    public void addContact(Contact contact) {
        executorService.execute(() -> {
            contactDao.insert(contact);
            contactApi.addContact(contact).enqueue(new Callback<Response<Contact>>() {
                @Override
                public void onResponse(Call<Response<Contact>> call, retrofit2.Response<Response<Contact>> response) {
                    if (response.isSuccessful() && response.body() != null) {
                        Object serverContact = response.body().getData();
                        executorService.execute(() -> {
                            contactDao.update(serverContact);
                        });
                    }
                }

                @Override
                public void onFailure(Call<Response<Contact>> call, Throwable t) {
                    // Handle failure
                }
            });
        });
    }

    public void updateContact(Object contact) {
        executorService.execute(() -> {
            contactDao.update(contact);
            contactApi.updateContact(contact).enqueue(new Callback<Response<Contact>>() {
                @Override
                public void onResponse(Call<Response<Contact>> call, retrofit2.Response<Response<Contact>> response) {
                    if (response.isSuccessful() && response.body() != null) {
                        Object serverContact = response.body().getData();
                        executorService.execute(() -> {
                            contactDao.update(serverContact);
                        });
                    }
                }

                @Override
                public void onFailure(Call<Response<Contact>> call, Throwable t) {
                    // Handle failure
                }
            });
        });
    }

    public void deleteContact(Contact contact) {
        executorService.execute(() -> {
            contactDao.delete(contact);
            contactApi.deleteContact(contact.getId()).enqueue(new Callback<Response<Void>>() {
                @Override
                public void onResponse(Call<Response<Void>> call, retrofit2.Response<Response<Void>> response) {
                    // Handle response
                }

                @Override
                public void onFailure(Call<Response<Void>> call, Throwable t) {
                    // Handle failure
                }
            });
        });
    }

    public void uploadAvatar(String contactId, Bitmap avatar) {
        executorService.execute(() -> {
            String base64Avatar = convertBitmapToBase64(avatar);
            contactApi.uploadAvatar(contactId, base64Avatar).enqueue(new Callback<Response<String>>() {
                @Override
                public void onResponse(Call<Response<String>> call, retrofit2.Response<Response<String>> response) {
                    if (response.isSuccessful() && response.body() != null) {
                        String avatarUrl = response.body().getData().toString();
                        executorService.execute(() -> {
                            contactDao.updateAvatar(contactId, avatarUrl);
                        });
                    }
                }

                @Override
                public void onFailure(Call<Response<String>> call, Throwable t) {
                    // Handle failure
                }
            });
        });
    }

    private void refreshContacts() {
        contactApi.getAllContacts().enqueue(new Callback<Response<List<Contact>>>() {
            @Override
            public void onResponse(Call<Response<List<Contact>>> call, retrofit2.Response<Response<List<Contact>>> response) {
                if (response.isSuccessful() && response.body() != null) {
                    List<Contact> contacts = (List<Contact>) response.body().getData();
                    executorService.execute(() -> {
                        for (Contact contact : contacts) {
                            contactDao.insert(contact);
                        }
                    });
                }
            }

            @Override
            public void onFailure(Call<Response<List<Contact>>> call, Throwable t) {
                // Handle failure
            }
        });
    }

    private String convertBitmapToBase64(Bitmap bitmap) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);
        byte[] byteArray = outputStream.toByteArray();
        return Base64.encodeToString(byteArray, Base64.DEFAULT);
    }
} 